function onReady(func){
	window.onload = func;
}

function domById(id) {
	return document.getElementById(id);
}

function contains(pNode, subNode) {
	if(pNode.contains){
		return pNode.contains(subNode);
	} else if (pNode.compareDocumentPosition) {
		return !!(pNode.compareDocumentPosition(subNode) & 16);
	} else {
		var node = subNode.parentNode;
		do {
			if(node === pNode ) {
				return true;
			} else {
				node = node.parentNode;
			}
		} while (node !== null);
		return false;
	} 
}
function getElementLeft(element) {
	var actualLeft = element.offsetLeft;
	var current = element.offsetParent;
	while(current !== null) {
		actualLeft += current.offsetLeft;
		current = current.offsetParent;
	}
	return actualLeft;
}
function getElementTop(element) {
	var actualTop = element.offsetTop;
	var current = element.offsetParent;
	while(current !== null) {
		actualTop += current.offsetTop;
		current = current.offsetParent;
	}
	return actualTop;
}
function getViewport() {
	if (document.compatMode == 'BackCompat') {
		return {
			width : document.body.clientWidth,
			height : document.body.clientHeight
		};
	} else {
		return {
			width : document.documentElement.clientWidth,
			height : document.documentElement.clientHeight
		};
	}
}

function loadScript(url) {
	var script = document.createElement('script');
	script.type = 'text/javascript';
	script.src = url;
	document.body.appendChild(script);
}
function loadScriptString(code) {
	var script = document.createElement('script');
	script.type = 'text/javascript';
	try {
		script.appendChild(document.createTextNode(code));
	} catch (e) {
		script.text = code;
	}
	document.body.appendChild(script);
}

//惰性载入函数
function createXHR() {
	if(XMLHttpRequest) {
		createXHR = function() {
			return new XMLHttpRequest();
		};
	} else if (ActiveXObject) {
		createXHR = function() {
			if(typeof arguments.callee.activeXString != 'string') {
				var versions = ['MSXML2.XMLHttp.6.0','MSXML2.XMLHttp.3.0','MSXML2.XMLHttp'];
				for(var i = 0,len = versions.length; i < len; i ++){
					try{
						var xhr = new ActiveXObject(versions[i]);
						arguments.callee.activeXString = versions[i];
						return xhr;
					} catch (e) {
					}
				}
			}
			return new ActiveXObject(arguments.calllee.activeXString);
		};
	} else {
		createXHR = function() {
			throw new Error('No XMLHttpRequest object available.');
		};
	}
	return createXHR();
}


var EventUtil = {
	addHandler : function (ele, type, handler) {
		if(ele.addEventListener) {
			ele.addEventListener(type, handler, false);
		} else if(ele.attachEvent) {
			ele.attachEvent('on' + type, handler);
		} else {
			ele['on' + type] = handler;
		}
	},
		
	getEvent : function (event) {
		return event || window.event;
	},
		
	getTarget : function (event) {
		return event.target || event.srcElement;
	},
	
	preventDefault : function (event) {
		if (event.preventDefault) {
			event.preventDefault();
		} else {
			event.returnValue = false;
		}
	},
		
	removeHandler : function (ele, type, handler) {
		if(ele.removeEventListener) {
			ele.removeEventListener(type, handler, false);
		} else if(ele.detachEvent) {
			ele.detachEvent('on' + type, handler);
		} else {
			ele['on' + type] = null;
		}
	},
	
	stopPropagation : function (event) {
		if (event.stopPropagation) {
			event.stopPropagation();
		} else {
			event.cancelBubble = true;
		}
	}
};

function EventTarget() {
	this.handlers = [];
}
EventTarget.prototype = {
	constructor : EventTarget,
	addHandler : function(type, handler) {
		if (typeof this.handlers[type] == 'undefined') {
			this.handlers[type] = [];
		}
		this.handlers[type].push(handler);
	},
	fire : function(event) {
		if (!event.target) {
			event.target = this;
		}
		if (this.handlers[event.type] instanceof Array) {
			var handlers = this.handlers[event.type];
			for(var i = 0, len = handlers.length; i < len; i ++) {
				handlers[i](event);
			}
		}
	},
	removeHandler : function(type, handler) {
		if (this.handlers[type] instanceof Array) {
			var handlers = this.handlers[type];
			for(var i = 0, len = handlers.length; i < len; i ++) {
				if (handlers[i] === handler) {
					break;
				}
			}
			handlers.splice(i, 1);
		}
	}
};

var DragDrop = function() {
	//被拖动的对象，DOM对象
	var draggingObj = null,
		
		//鼠标按下时，拖动对象与鼠标横、纵坐标差值
		deltX = 0, deltY = 0,
			
		//自定义时间对象
		dragEventTarget = new EventTarget(),
		
		//一些样式，移动时要改变的
		objStyle = [
			{
				attr : 'onselectstart',
				newValue : 'return false',
				oldValue : null
			},
			{
				attr : 'cursor',
				newValue : 'pointer',
				oldValue : null
			}
		],
		//html对象
		htmlElement = document.getElementsByTagName('html')[0];
	
	//绑定在document上的处理事件
	function handleEvent(event) {
		event = EventUtil.getEvent(event);
		var target = EventUtil.getTarget(event);
		switch (event.type) {
			case 'mousedown' :
			if (target.className.indexOf('draggable') > -1) {
				draggingObj = target;
				draggingObj.style.position = 'absolute';
				deltX = event.clientX - target.offsetLeft;
				deltY = event.clientY - target.offsetTop;
				dragEventTarget.fire({
					type : 'dragstart',
					target : draggingObj,
					x : event.clientX,
					y : event.clientY
				});
				
				var objStyle0 = objStyle[0];
				objStyle0.oldValue = htmlElement.getAttribute( objStyle0.attr );
				htmlElement.setAttribute(objStyle0.attr, objStyle0.newValue);
				for(var i = 1 , len = objStyle.length; i < len; i ++){
					var style = objStyle[i];
					style.oldValue = draggingObj.style[style.attr];
					draggingObj.style[style.attr] = style.newValue;
				}
			}
			
			break;
			
			case 'mousemove' : 
			if (draggingObj !== null) {
				event = EventUtil.getEvent(event);
				var x = event.clientX;
				var y = event.clientY;
				//drag here
				draggingObj.style.left = (x - deltX) + 'px';
				draggingObj.style.top = (y - deltY) + 'px';
				dragEventTarget.fire({
					type : 'drag',
					target : draggingObj,
					x : x,
					y : y
				});
			}
			break;
			
			case 'mouseup' : 
			if( draggingObj !== null ) {
				var objStyle0 = objStyle[0];
				objStyle0.oldValue == null ? 
					htmlElement.removeAttribute(objStyle0.attr) : 
					htmlElement.setAttribute(objStyle0.attr, objStyle0.oldValue) ;
			
				for(var i = 1 , len = objStyle.length; i < len; i ++){
					var style = objStyle[i];
					style.oldValue == null ? 
						draggingObj.style.removeProperty(style.attr) : 
						draggingObj.style[style.attr] = style.oldValue;
				}
				
				dragEventTarget.fire({
					type : 'dragend',
					target : draggingObj,
					x : event.clientX,
					y : event.clientY
				});
					
				draggingObj = null;
			}
			break;
		}
	};
	
	dragEventTarget.enable = function(){
		
		EventUtil.addHandler(document, 'mousedown', handleEvent);
		EventUtil.addHandler(document, 'mousemove', handleEvent);
		EventUtil.addHandler(document, 'mouseup', handleEvent);
	};
			
	dragEventTarget.disable = function(){
		EventUtil.removeHandler(document, 'mousedown', handleEvent);
		EventUtil.removeHandler(document, 'mousemove', handleEvent);
		EventUtil.removeHandler(document, 'mouseup', handleEvent);
	};
	
	return dragEventTarget;
}();